import sqlite3
import hashlib
import asyncio

from . import config

DB_PATH = "config/users.db"  # 数据库路径
# task_list: list[tuple[str, bool, asyncio.Future, tuple]] = []
# thread_list: dict[int, asyncio.Task] = {}
# use_tasks_num = MIN_THREAD
# thread_id = 0

SALT = "neutron"


def hash_password(password):
    return hashlib.sha256((password+SALT).encode()).hexdigest()


def init():
    userdb = sqlite3.connect(DB_PATH)
    userdb.execute(  # 用户表
        "CREATE TABLE IF NOT EXISTS users (username TEXT PRIMARY KEY , password TEXT NOT NULL)")
    userdb.execute(  # 权限表
        "CREATE TABLE IF NOT EXISTS vfs (id INTEGER PRIMARY KEY AUTOINCREMENT , username TEXT NOT NULL , dirpath TEXT NOT NULL , permission INTEGER NOT NULL, UNIQUE(username, dirpath))")
    userdb.execute(  # 会话表
        "CREATE TABLE IF NOT EXISTS `session` (username TEXT PRIMARY KEY , `session` BLOB NOT NULL)")
    if (config.read("account")["password"] != ""):
        # 初始化用户
        userdb.execute("INSERT OR REPLACE INTO users (username, password) VALUES (?, ?)",
                       (config.read("account")["username"], hash_password(
                           config.read("account")["password"])))
        userdb.execute("INSERT OR REPLACE INTO vfs (username, dirpath, permission) VALUES (?, ?, ?)",
                       (config.read("account")["username"], "/", 2))
    userdb.commit()


async def execute(cmd: str, need_commit: bool = False, args: tuple = (), get_rowcount: bool = False):
    def run():  # 执行
        try:
            session = sqlite3.connect(DB_PATH)
            cursor = session.cursor()
            cursor.execute(cmd, args)
            res = (cursor.fetchall())
            if (need_commit):
                session.commit()
            return res
        except Exception as e:
            return e  # 特别处理 to_thread 异常处理
    ret = await asyncio.to_thread(run)
    if (isinstance(ret, Exception)):
        raise ret
    return ret


async def execute_rc(cmd: str, need_commit: bool = False, args: tuple = (), get_rowcount: bool = False):
    def run():  # 执行并返回影响行数
        try:
            session = sqlite3.connect(DB_PATH)
            cursor = session.cursor()
            cursor.execute(cmd, args)
            res = (cursor.rowcount)
            if (need_commit):
                session.commit()
            return res
        except Exception as e:
            return e
    ret = await asyncio.to_thread(run)
    if (isinstance(ret, Exception)):
        raise ret
    return ret
